home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-12-28 | 8.4 KB | 321 lines | [TEXT/MPS ] |
- (*******************************************************************
-
- Transfer Menu.p
-
- MDEF for dynamic Transfer menu demo.
-
- (c) 1988, by Clifford Story & Attic Software
-
- *******************************************************************)
-
- unit Transfermenu;
-
- (******************************************************************)
-
- interface
-
- (******************************************************************)
-
- uses memtypes, quickdraw, osintf, toolintf, Common;
-
- (******************************************************************)
-
- procedure menudef(message : integer; themenu : MenuHandle;
- var menurect : Rect; hitpoint : Point;
- var whichitem : integer);
-
- (******************************************************************)
-
- implementation
-
- (******************************************************************)
-
- type
-
- QDrecord = record
- randSeed : long;
- screenBits : BitMap;
- arrow : Cursor;
- dkGray : Pattern;
- ltGray : Pattern;
- gray : Pattern;
- black : Pattern;
- white : Pattern;
- thePort : GrafPtr;
- end;
- QDpointer = ^QDrecord;
-
- (******************************************************************)
-
- procedure menudraw(themenu : MenuHandle; var menurect : Rect); forward;
- procedure menuchoose(themenu : MenuHandle; var menurect : Rect;
- hitpoint : Point; var whichitem : integer); forward;
- procedure menusize(themenu : MenuHandle); forward;
-
- (******************************************************************)
-
- {$R-}
- {$SC+}
-
- (*******************************************************************
-
- menudef
- -------
-
- An MDEF is called to do three different things: draw the menu,
- hit-test a mouse location, or calculate the menu dimensions.
- The “message” parameter determines which service is requested,
- so the MDEF simply branches on “message” to specialized routines
- that handle the specific functions.
-
- *******************************************************************)
-
- procedure menudef(message : integer; themenu : MenuHandle;
- var menurect : Rect; hitpoint : Point;
- var whichitem : integer);
-
- begin
-
- case message of
- mDrawMsg : menudraw(themenu, menurect);
- mChooseMsg : menuchoose(themenu, menurect,
- hitpoint, whichitem);
- mSizeMsg : menusize(themenu);
- end;
-
- end;
-
- (******************************************************************
-
- qdglobals
- ---------
-
- The qdglobals function returns a pointer to the quickdraw
- globals. This allows procedure definitions and desk accessories
- to access the QD globals even though they can't call InitGraf.
-
- ******************************************************************)
-
- function QDglobals : QDpointer;
-
- var
- thepointer : longpointer;
-
- begin
-
- thepointer := longpointer(currenta5);
- thepointer := longpointer(thepointer^);
- QDglobals := QDpointer(long(thepointer^)
- - sizeof(QDrecord) + sizeof(GrafPtr));
-
- end;
-
- (*******************************************************************
-
- menudraw
- --------
-
- The “menudraw” routine draws the menu.
-
- The first item is the “Transfer...” command, the second is the
- “Edit Transfer...” command, and the third is the separating Line
- before the list of applications. If there are no applications
- in the list, then the list cannot be edited and so the second
- item should be grayed out.
-
- The remaining items are found in the Transfer list that is kept
- in the “TRNS” resource. Each element of the list includes the
- name of the application, which is drawn on the menu.
-
- *******************************************************************)
-
- procedure menudraw(themenu: MenuHandle; var menurect: Rect);
-
- var
- thehandle : thandle;
- height : integer;
- width : integer;
- therect : Rect;
- index : integer;
- thestring : Str255;
-
- begin
-
- thehandle := thandle(GetResource('TRNS', 1001));
- HLock(Handle(thehandle));
-
- height := menurect.top + 12;
- width := menurect.left + 12;
-
- MoveTo(width, height);
- DrawString('Transfer...');
- MoveTo(menurect.right - CharWidth('T') - 15, height);
- DrawChar(chr(17));
- DrawChar('T');
-
- height := height + 16;
- MoveTo(width, height);
- DrawString('Edit Menu...');
-
- if thehandle^^.count = 0 then begin
- PenPat(QDglobals^.gray);
- PenMode(patBic);
- with menurect do
- SetRect(therect, left, top + 16, right, top + 32);
- PaintRect(therect);
- PenNormal;
- end;
-
- height := height + 16;
- MoveTo(menurect.left, menurect.top + 40);
- Line(menurect.right - menurect.left, 0);
-
- for index := 1 to thehandle^^.count do begin
- height := height + 16;
- MoveTo(width, height);
- BlockMove(@thehandle^^.appl[index].name, @thestring, 32);
- DrawString(thestring);
- end;
-
- HUnlock(Handle(thehandle));
-
- end;
-
- (*******************************************************************
-
- menuchoose
- ----------
-
- This routine is passed the mouse position, and sets the
- “whichitem” parameter to the corresponding menu item.
-
- Since all the menu items are the same height, it's easy to
- determine which one the mouse is in - provided it's somewhere
- in the menu. If it isn't, the routine should return zero in
- the “whichitem” parameter.
-
- The routine should also return zero if the mouse is in the
- dividing Line (item 3) or if it is in the “Edit Menu...” item
- (item 2) and there are no applications to edit (it which case
- the draw routine would have grayed out this item).
-
- Finally, if the mouse is in an active item, and that item is
- different from the original value of “whichitem”, then the old
- item should be un-highlighted, and the new one highlighted.
-
- *******************************************************************)
-
- procedure menuchoose(themenu : MenuHandle; var menurect : Rect;
- hitpoint : Point; var whichitem : integer);
-
- var
- theitem : integer;
- thehandle : thandle;
- therect : Rect;
-
- begin
-
- if PtInRect(hitpoint, menurect) then
- theitem := 1 + ((hitpoint.v - menurect.top) div 16)
- else
- theitem := 0;
-
- if theitem = 3 then
- theitem := 0
- else if theitem = 2 then begin
- thehandle := thandle(GetResource('TRNS', 1001));
- if thehandle^^.count = 0 then
- theitem := 0;
- end;
-
- if theitem <> whichitem then begin
-
- therect := menurect;
- therect.bottom := therect.top + 16 * theitem;
- therect.top := therect.bottom - 16;
- InvertRect(therect);
-
- if whichitem > 0 then begin
- OffsetRect(therect, 0, 16 * (whichitem - theitem));
- InvertRect(therect);
- end;
-
- whichitem := theitem;
-
- end;
-
- end;
-
- (*******************************************************************
-
- menusize
- --------
-
- This routine calculates the dimensions of the menu rectangle.
-
- The height is easy; the “TRNS” resource reveals the number of
- applications listed on the menu; add the first three items and
- multiply by 16.
-
- The width is found by walking the menu and finding the widest
- item. There are some adjustments for white space around the
- individual items.
-
- A note: Odd things happened in this routine, with the String
- width changing as windows were opened. I can't figure why this
- occurred, since Inside Mac says the Menu Manager sets the port
- to the Window Manager port. Anyway, the TextFont, TextSize and
- TextFace calls cleared up the problem.
-
- *******************************************************************)
-
- procedure menusize(themenu : MenuHandle);
-
- var
- savedload : logical;
- thewidth : integer;
- thehandle : thandle;
- index : integer;
- thestring : Str255;
- newwidth : integer;
-
- begin
-
- savedload := logical(Ptr(resload)^);
- SetResLoad(true);
-
- TextFont(systemFont);
- TextSize(12);
- TextFace([]);
-
- thewidth := StringWidth('Transfer...')
- + CharWidth('T') + 39;
- newwidth := StringWidth('Edit Menu...') + 16;
- if newwidth > thewidth then
- thewidth := newwidth;
-
- thehandle := thandle(GetResource('TRNS', 1001));
- HLock(Handle(thehandle));
-
- for index := 1 to thehandle^^.count do begin
- BlockMove(@thehandle^^.appl[index].name, @thestring, 32);
- newwidth := StringWidth(thestring) + 16;
- if newwidth > thewidth then
- thewidth := newwidth;
- end;
-
- HUnlock(Handle(thehandle));
-
- themenu^^.menuHeight := 48 + 16 * thehandle^^.count;
- themenu^^.menuWidth := thewidth;
-
- SetResLoad(savedload);
-
- end;
-
- (******************************************************************)
-
- end.
-
- (******************************************************************)
-